简明Python教程(A Byte of Python中文版)

参考资料地址:https://github.com/LenKiMo/byte-of-python(中文版)

https://github.com/swaroopch/byte-of-python(英文版)

https://python.swaroopch.com/(英文版)

注意点:

1. Python特点:解释性语言(无需编译成二进制码,直接源码->字节码->电脑语言)、强面向对象  //字节码文件以.pyc为扩展名,独立于运行平台

2. 变量:无需声明或定义数据类型;没有long和char类型

3. 格式化方法:format()函数

4. 换行连接

  • 显示行连接:利用"\"连接多行  //后面立即接换行
  • 隐式行连接:以括号开始的多行

5. Python 对块使用缩进,不使用大括号,同一组语句(块)缩进必须相同  //建议统一用四个空格进行缩进

6. 运算符:整除为“//”

7. 控制流:Python不存在switch语句;while和for语句可以拥有else子句

8. 函数

(1)函数参数:

  • 定义函数时给定的名称称作“形参”,调用函数时提供给函数的值称作“实参”
  • 默认参数值:在定义时进行赋值  //有默认参数值的参数必须位于参数列表的末尾
  • 关键字参数:使用命名(关键字)而非位置来指定函数中的参数  //优点:无需考虑参数顺序;仅需对部分指定参数进行赋值,其他的参数使用默认值
  • 可变参数(参数数量是可变的):def func(param1, *param2, **param3),如:
1 def total(a=5, *numbers, **phonebook):
2     print('a', a)
3     #遍历元组中的所有项目
4     for single_item in numbers:
5         print('single_item', single_item)
6     #遍历字典中的所有项目
7     for first_part, second_part in phonebook.items():
8         print(first_part,second_part)
9 print(total(10,1,2,3,Jack=1123,John=2231,Inge=1560))           

其中,*param2参数表明所有未指定的位置参数将构成名称为“param2”的元组(Tuple),而**param3则表明所有未指定的关键字参数将构成名字为“param3”的字典(dictionary)

(2)变量作用域

局部变量:变量的作用域为被定义的块,如函数内变量

全局变量:使用global语句进行声明后再使用

(3)文档字符串(DocStrings):用于在函数定义开始对程序功能进行说明,如 def print_max(x, y):

 2     '''Prints the maximum of two numbers.打印两个数值中的最大数。
 3     The two values must be integers.这两个数都应该是整数'''
 4     # 如果可能,将其转换至整数类型
 5     x = int(x)
 6     y = int(y)
 7     if x > y:
 8         print(x, 'is maximum')
 9     else:
10         print(y, 'is maximum')
11 
12 print_max(3, 5)
13 print(print_max.__doc__)      #使用函数对象的__doc__属性 ,也可使用help函数:help(print_max),或者pydoc命令

注:文档字符串一般约定为一串多行字符串,其中第一行以某一大写字母开始,以句号结束。第二行为空行,后跟的第三行开始是任何详细的解释说明。

 9. 模块(以.py为后缀名,包含函数与变量的文件)

(1)导入模块

  • (建议)利用import语句导入模块:如import sys  //Python从当前程序目录sys.path变量所提供的目录进行模块搜索;sys.path的值与环境变量PYTHONPATH等同
  • 利用from...import...语句  //应避免使用,防止程序中出现命名冲突
  • 利用from...import *导入模块中所有公共名称  //避免使用

(2)常用模块

import os, time

  • print(os.getcwd())  //输出当前目录
  • os.sep  //当前操作系统所采用的分隔符(便于程序可移植),Linux为“/”,Windows为“\\”(转义\),Mac为“:”
  • os.path.exists()  //判断目录路径是否存在
  • os.mkdir()  //创建目录
  • time.strftime()  //将当前日期转化为字符串,可以设置显示格式
  • os.system()  //使命令从系统中运行,如shell
  • os.remove()  //删除文件

(3)模块的名称__name__属性,用于确定所在模块的名称,如利用__name__确定模块是独立运行还是被导入进来运行:

1 if __name__ == '__main__':
2     print('This program is being run by itself')
3 else:
4     print('I am being imported from another module')

注:每一个 Python 模块都定义了它的 __name__ 属性。如果它与 __main__ 属性相同则代表这一模块是由用户独立运行的

(4)dir()函数  //内置函数返回由对象所定义的名称列表,如果参数是模块名称,函数将返回这一指定模块的名称列表(函数、类、变量);如果没有提供参数,函数将返回当前模块的名称列表。  //del语句用于删除变量或名称,如del a

(5)包(Packages):组织模块的层次结构  //from 包.模块 import ...  需要包文件夹位于python的搜索路径——环境变量PYTHONPATH

包是指一个包含模块与一个特殊的__init__.py文件的文件夹  //__init__.py表明这一文件夹包含Python模块

#创建一个名为“world”的包,其中还包含着 “asia”、“africa”等其它子包
#同时这些子包都包含了诸如“india”、“madagascar”等模块。
1
- <some folder present in the sys.path>/ 2 - world/ 3 - __init__.py 4 - asia/ 5 - __init__.py 6 - india/ 7 - __init__.py 8 - foo.py 9 - africa/ 10 - __init__.py 11 - madagascar/ 12 - __init__.py 13 - bar.py

10. 数据结构

(1)列表(可变数据类型):利用方括号定义,如shoplist = ['apple', 'mango', 'carrot', 'banana']  //help(list)查看更多细节

(2)元组(不可变数据类型):将多个对象保存在一起,建议利用圆括号定义,如zoo = ('python', 'elephant', 'penguin'),单项目元组 singleton = (2, )   //help(tuple)

(3)字典(可变数据类型):存储“键-值”对(类似地址簿),利用花括号定义,如d = {key : value1 , key2 : value2},其中键必须是不可变的对象(如字符串),且字典中不同“键-值”对是无序的  //help(dict)

(4)序列:列表、元组和字符串均可以看作序列(Sequence)的某种表现形式,序列的主要功能是资格测试(in和not in表达式)和索引操作(从0开始)

(5)集合:简单对象的无序集合,如bri = set(['brazil', 'russia', 'india'])  //help(set)

(6)利用变量创建对象,变量仅仅是对对象的一个引用(refer),即变量名仅指向对象在内存中的地址,也被视为将名称绑定(Binding)到对象上;示例代码如下:

 1 print('Simple Assignment')
 2 shoplist = ['apple', 'mango', 'carrot', 'banana']
 3 # mylist 只是指向同一对象的另一种名称
 4 mylist = shoplist  #简单赋值,不创建副本
 5 # 我购买了第一项项目,所以我将其从列表中删除
 6 del shoplist[0]
 7 print('shoplist is', shoplist)
 8 print('mylist is', mylist)
 9 # 注意到 shoplist 和 mylist 二者都
10 # 打印出了其中都没有 apple 的同样的列表,以此我们确认
11 # 它们指向的是同一个对象
12 print('Copy by making a full slice')
13 # 通过生成一份完整的切片制作一份列表的副本
14 mylist = shoplist[:]  #切片操作创建新的副本
15 # 删除第一个项目
16 del mylist[0]
17 print('shoplist is', shoplist)
18 print('mylist is', mylist)
19 # 注意到现在两份列表已出现不同

注:列表等复杂对象的赋值语句只是对同一对象的“查阅”,如果需要创建副本,必须使用切片操作制作副本

 11. 面向对象编程

对象(object)是类(class)的实例(instance),包含两种属性(attribute):字段(变量)、方法(函数)

(1)类方法和普通函数的区别:类方法的第一个参数必须为self(引用对象本身)且不可缺省,但是调用时无需显式赋值  //相当于C++中的指针以及Java与C#中的this指针

(2)__init__()方法:进行对象初始化,且无需显式调用  //前后均为双下划线

 1 class Person:
 2     def __init__(self, name):  #无需显式调用
 3         self.name = name
 4     def say_hi(self):
 5         print('Hello, my name is', self.name)
 6 
 7 p = Person('Swaroop')
 8 p.say_hi()
 9 # 前面两行同时也能写作
10 # Person('Swaroop').say_hi()    

(3)类变量和对象变量:类变量为该类的所有实例共享,对象变量为类的实例对象独立拥有

 1 # coding=UTF-8
 2 class Robot:
 3     """表示有一个带有名字的机器人。"""
 4     # 一个类变量,用来计数机器人的数量
 5     population = 0
 6     def __init__(self, name):
 7         """初始化数据"""
 8         self.name = name
 9         print("(Initializing {})".format(self.name))
10         # 当有人被创建时,机器人
11         # 将会增加人口数量
12         Robot.population += 1  #等同于self.__class__.population += 1
13 
14     def die(self):
15         """我挂了。"""
16         print("{} is being destroyed!".format(self.name))
17         Robot.population -= 1
18         if Robot.population == 0:
19             print("{} was the last one.".format(self.name))
20         else:
21             print("There are still {:d} robots working.".format(Robot.population))
22    
23      def say_hi(self):
24         """来自机器人的诚挚问候
25         没问题,你做得到。"""
26         print("Greetings, my masters call me {}.".format(self.name))
27 
28     @classmethod  #类方法,使用装饰器Decorator将how_many标记为类方法
29     def how_many(cls):
30         """打印出当前的人口数量"""
31         print("We have {:d} robots.".format(cls.population))
32 
33 droid1 = Robot("R2-D2")
34 droid1.say_hi()
35 Robot.how_many()
36 
37 droid2 = Robot("C-3PO")
38 droid2.say_hi()
39 Robot.how_many()
40 
41 print("\nRobots can do some work here.\n")
42 print("Robots have finished their work. So let's destroy them.")
43 droid1.die()
44 droid2.die()
45 
46 Robot.how_many()

注:

  • 所有的类成员都是公开的,如果使用数据成员并在其名字中使用双下划线作为前缀,形成诸如 __privatevar这样的形式,Python会使用名称调整来使其有效地成为一个私有变量;因此,建议遵循如下约定:任何在类或对象之中使用的变量其命名应以下划线开头,其它所有非此格式的名称都将是公开的,并可以为其它任何类或对象所使用。
  • 装饰器(Decorators)是应用包装函数的快捷方式,有助于将某一功能与一些代码一遍又一遍地“包装”
  • python装饰器的通俗理解:https://blog.csdn.net/u013471155/article/details/68960244

(4)继承:基类/超类、派生类/子类、多态性(子类型对象可以看作父类的实例

 1 # coding=UTF-8
 2 class SchoolMember:
 3     '''代表任何学校里的成员。'''
 4     def __init__(self, name, age):
 5         self.name = name
 6         self.age = age
 7         print('(Initialized SchoolMember: {})'.format(self.name))
 8 
 9     def tell(self):
10         '''告诉我有关我的细节。'''
11         print('Name:"{}" Age:"{}"'.format(self.name, self.age), end=" ")
12 
13 class Teacher(SchoolMember):  #继承,参数为包含基类名称的元组
14     '''代表一位老师。'''
15     def __init__(self, name, age, salary):
16         SchoolMember.__init__(self, name, age)  #子类定义__init__的情况下需要显式调用父类构造函数__init__
17         self.salary = salary
18         print('(Initialized Teacher: {})'.format(self.name))
19 
20     def tell(self):
21         SchoolMember.tell(self)  #子类对象作为父类方法的实例参数
22         print('Salary: "{:d}"'.format(self.salary))
23 
24 class Student(SchoolMember):
25     '''代表一位学生。'''
26     def __init__(self, name, age, marks):
27         SchoolMember.__init__(self, name, age)
28         self.marks = marks
29         print('(Initialized Student: {})'.format(self.name))
30 
31     def tell(self):
32         SchoolMember.tell(self)
33         print('Marks: "{:d}"'.format(self.marks))
34 
35 t = Teacher('Mrs. Shrividya', 40, 30000)
36 s = Student('Swaroop', 25, 75)
37 # 打印一行空白行
38 print()
39 
40 members = [t, s]
41 for member in members:
42     # 对全体师生工作
43     member.tell()

 12. 输入与输出

(1)用户输入内容:input()函数

(2)文件:创建(open)一个属于file类的对象并适当使用它的read、readline、write方法

 1 poem = '''\
 2 Programming is fun
 3 When the work is done
 4 if you wanna make your work also fun:
 5 use Python!
 6 '''
 7 
 8 # 打开文件以编辑('w'riting)
 9 f = open('poem.txt', 'w')
10 # 向文件中编写文本
11 f.write(poem)
12 # 关闭文件,保证内容已经被写入到文件
13 f.close()
14 
15 # 如果没有特别指定,
16 # 将假定启用默认的阅读('r'ead)模式
17 f = open('poem.txt')
18 while True:
19     line = f.readline()
20     # 零长度指示 EOF
21     if len(line) == 0:
22     break
23     # 每行(`line`)的末尾
24     # 都已经有了换行符
25     #因为它是从一个文件中进行读取的
26     print(line, end='')
27 # 关闭文件
28 f.close()

(3)pickle标准模块:将任何纯Python对象存储到一个文件中,并在稍后将其取回

 1 import pickle
 2 
 3 # The name of the file where we will store the object
 4 shoplistfile = 'shoplist.data'
 5 # The list of things to buy
 6 shoplist = ['apple', 'mango', 'carrot']
 7 
 8 # Write to the file
 9 f = open(shoplistfile, 'wb')
10 # Dump the object to a file
11 pickle.dump(shoplist, f)  #封装
12 f.close()
13 
14 # Destroy the shoplist variable
15 del shoplist
16 
17 # Read back from the storage
18 f = open(shoplistfile, 'rb')
19 # Load the object from the file
20 storedlist = pickle.load(f)  #拆封
21 print(storedlist)

13. 异常

(1)try..except...语句:检查语句,并根据异常类型进行相应的处理

1 try:  
2     text = input('Enter something --> ')  #需要检查的语句块
3 except EOFError:  #捕获异常类型
4     print('Why did you do an EOF on me?')
5 except KeyboardInterrupt:
6     print('You cancelled the operation.')
7 else:
8     print('You entered {}'.format(text))

(2)raise语句:主动抛出异常对象,引发异常处理

 1 # encoding=UTF-8
 2 
 3 class ShortInputException(Exception):  #继承自Exception类
 4     '''一个由用户定义的异常类'''
 5     def __init__(self, length, atleast):
 6         Exception.__init__(self)
 7         self.length = length
 8         self.atleast = atleast
 9 
10 try:
11     text = input('Enter something --> ')
12     if len(text) < 3:
13         raise ShortInputException(len(text), 3)  #抛出自定义异常
14     # 其他工作能在此处继续正常运行
15 except EOFError:
16     print('Why did you do an EOF on me?')
17 except ShortInputException as ex:  #捕获自定义异常
18     print(('ShortInputException: The input was ' + '{0} long, expected at least {1}').format(ex.length, ex.atleast))
19 else:
20     print('No exception was raised.')    

(3)try...finally...:确保finally出的语句块被执行,例如确保文件对象的正确关闭

 1 import sys
 2 import time
 3 
 4 f = None
 5 try:
 6     f = open("poem.txt")
 7     # 我们常用的文件阅读风格
 8     while True:
 9         line = f.readline()
10         if len(line) == 0:
11             break
12         print(line, end='')
13         sys.stdout.flush()  #将输出立即打印到屏幕
14         print("Press ctrl+c now")
15         # 为了确保它能运行一段时间
16         time.sleep(2)  #休眠两秒
17 except IOError:
18     print("Could not find file poem.txt")
19 except KeyboardInterrupt:
20     print("!! You cancelled the reading from the file.")
21 finally:  #该部分子句一定会执行
22     if f:
23         f.close()
24     print("(Cleaning up: Closed the file)")    

注:确保文件关闭的快捷方式——with语句(避免显示调用try...finally语句)

#with语句会获取由open语句返回的对象‘thefile’,并在代码块开始前调用thefile.__enter__函数,在代码块执行完毕之后调用thefile.__exit__
1
with open("poem.txt") as f:  #将关闭文件的操作交由with open来自动完成(__exit__方法) 2 for line in f: 3 print(line, end='')

14. 标准库(https://docs.python.org/3/library/)

 (1)sys模块:

 sys.argv:命令行参数,如查看Python软件版本sys.version_info

(2)logging日志模块:用于记录信息

(3)os模块:用于和操作系统交互

(4)platform模块:用于获取平台(操作系统)的信息

 1 import os
 2 import platform
 3 import logging
 4 
 5 if platform.platform().startswith('Windows'):  #返回正在使用的操作系统
 6     logging_file = os.path.join(os.getenv('HOMEDRIVE'), os.getenv('HOMEPATH'), 'test.log')
 7 else:
 8     logging_file = os.path.join(os.getenv('HOME'), 'test.log')
 9 
10 print("Logging to", logging_file)
11 logging.basicConfig(
12     level=logging.DEBUG,
13     format='%(asctime)s : %(levelname)s : %(message)s',
14     filename=logging_file,
15     filemode='w',
16 )
17 
18 logging.debug("Start of the program")
19 logging.info("Doing something")
20 logging.warning("Dying now")

15. 更多。。。(建议参考PDF原文

(1)函数返回多个值:传递元组

(2)特殊方法:用来模拟内置类型的某些行为

  •  __init__(self, ...):初始化,在新创建的对象被返回准备使用时被调用
  • __del__(self):在对象被删除之前调用(它的使用时机不可预测,所以避免使用它)
  • __str__(self):使用print函数时,或str()被使用时被调用
  • __lt__(self, other):当小于运算符(<)被使用时被调用。类似地,其它所有运算符(+、> 等等)也存在相应的特殊方法
  • __getitem__(self, key):使用x[key]索引操作时会被调用
  • __len__(self):针对序列对象使用内置len()函数时会被调用

(3)单语句块:如果语句块只包括单独的一句语句时,可以在同一行指定它,如条件语句和循环语句,如if flag: print('Yes')

注:单语句块是在原地立即执行,不会被看作单独的语句块,但是会影响程序整体的工整性,不建议使用

(4)lambda语句:可以创建一个新的函数对象;从本质上说, lambda 需要一个参数,后跟一个表达式作为函数体,这一表达式执行的值将作为这个新函数的返回值

1 points = [{'x': 2, 'y': 3}, {'x': 4, 'y': 1}]
2 points.sort(key=lambda i: i['y'])  #调用list的sort方法,通过获得一个key参数,用以决定列表的排序方式
3 print(points)

注:lambda表达式用于实现仅使用一次的简单函数,而无需编写独立的def块

(4)列表推导:用于从一份现有的列表中得到一份新列表,可避免显式调用循环过程,减少代码量

1 listone = [2, 3, 4]
2 listtwo = [2*i for i in listone if i > 2]
3 print(listtwo)

(5)assert语句:用于断言(判断)某事是真的;断言失败时,会抛出错误AssertionError

1 import numpy as np
2 a = np.random.randn((5,1))
3 assert(a.shape = (5,1))  #保证数组a的大小是正确的

注:在大多数情况下,明智地选用 assert 语句好过捕获异常,也好过定位问题或向用户显示错误信息然后退出

posted @ 2019-01-12 11:08  从头再来,不要慌  阅读(39140)  评论(0编辑  收藏  举报